home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / mus / play / multiplsr.lha / ptsplay.asm < prev    next >
Assembly Source File  |  1992-09-14  |  42KB  |  1,585 lines

  1. * MultiPlayer
  2. * Copyright (C) 1992 Bryan Ford
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * I (the author of MultiPlayer) can be contacted on the Internet at
  19. * "bryan.ford@m.cc.utah.edu".  See "Player.doc" for other addresses.
  20. *
  21. * This Protracker playroutine is very heavily modified from the one
  22. * supplied with Protracker 1.1b, 1.2, and 2.1.  (All of these versions
  23. * used the same player code.)  In particular, it uses the NotePlayer
  24. * system to play notes instead of going to the hardware.  It also
  25. * contains many bug fixes and compatibility enhancements (such as the
  26. * ability to play 15-instrument modules).
  27. *
  28. * Note that while most previous MutantTracker play routines were
  29. * public domain, this version is expressly taken out of the public
  30. * domain and brought under the GNU General Public License.
  31. *
  32. * $Id: ptsplay.asm,v 5.5 92/09/14 18:42:54 BAF Exp $
  33. *
  34.  
  35.  
  36.  
  37.  
  38. ; This is THE ONLY 100% FIXED VERSION of the PROTRACKER PLAYROUTINE!!!
  39. ;
  40. ; Please spread this WORLDWIDE as we are are fed up with utilities
  41. ; using the bugged playroutine supplied with the original Protracker
  42. ; release archieve.
  43. ;
  44. ; Some utils I hope to see with the 100% FIXED playroutine SOON:
  45. ;
  46. ; PTPlayer  -command by TSM/Vision
  47. ; Chameleon Music Player (ChamPlay)
  48. ; Noiseplayer by TRSI
  49. ;
  50. ; ...and all other utils playing PROTRACKER MODULES!!!
  51. ;
  52. ; ///BUG/// -*- N E T W O R K -*-
  53. ;
  54. ; Cool musicians write to: Noiseless
  55. ;                          Box 5036
  56. ;                          6021 Alesund
  57. ;                          Norway
  58.  
  59.  
  60.  
  61.  
  62. ;********************************************  ; 100% FIXED VERSION
  63. ;* ----- Protracker V1.1B Playroutine ----- *
  64. ;* Lars "Zap" Hamre/Amiga Freelancers 1991  *
  65. ;* Bekkeliveien 10, N-2010 STRØMMEN, Norway *
  66. ;********************************************
  67.  
  68. ; VBlank Version 2.01:
  69.  
  70. ; Call mt_init to initialize the routine, then call mt_music on
  71. ; each vertical blank (50 Hz). To end the song and turn off all
  72. ; voices, call mt_end.
  73.  
  74. ; This playroutine is not very fast, optimized or well commented,
  75. ; but all the new commands in PT1.1A should work.
  76. ; If it's not good enough, you'll have to change it yourself.
  77. ; We'll try to write a faster routine soon...
  78.  
  79. ; Changes from V1.0C playroutine:
  80. ; - Vibrato depth changed to be compatible with Noisetracker 2.0.
  81. ;   You'll have to double all vib. depths on old PT modules.
  82. ; - Funk Repeat changed to Invert Loop.
  83. ; - Period set back earlier when stopping an effect.
  84.  
  85.  
  86.  
  87.         include "exec/types.i"
  88.         include "exec/ables.i"
  89.         include "exec/execbase.i"
  90.         include "hardware/custom.i"
  91.         include "player.i"
  92.         include "bry/macros.i"
  93.  
  94. _intena equ (CUSTOM+intena)
  95.  
  96. NoteInfo        equ     $00
  97. NoteInit        equ     $04
  98. NoteFinish      equ     $08
  99. NoteStart       equ     $0c
  100. NoteStop        equ     $10
  101. NoteFreqVol     equ     $14
  102. NoteFreq        equ     $18
  103. NoteVol         equ     $1c
  104.  
  105.         xref    modmem,modend,intsongpos,intrepeat,getfreqmodspeed,hookfunc
  106.         xref    ntgetsongname,ntgetsongauthor,intflashnote,intflashsample,intflashscroll,changetintcia
  107.         xref    scrollmod,scrolllines,notetab,modflags,filter,modtype
  108.  
  109.         xdef    ntstart,ptfilter
  110.  
  111.         code    text
  112.  
  113. ntstart:
  114.         ori.b   #MTF_PROTRACKER!MTF_FILTER,modtype(a4)
  115.         plstartret 9$
  116.  
  117.         cnop    0,4
  118.         dc.l    gmod_GetScroll+4
  119. 9$      gmodbra init                    ; InitMusic
  120.         gmodbra start                   ; StartMusic
  121.         gmodbra mt_stop                 ; StopMusic
  122.         gmodbra fin                     ; EndMusic
  123.         gmodbra noteplayersave          ; NotePlayer
  124.         gmodq   1                       ; ContinueMusic
  125.         gmodnop
  126.         gmodnop
  127.         gmodnop
  128.         gmodnop
  129.         gmodnop
  130.         gmodnop
  131.         gmodnop
  132.         gmodbra ntgetsongname           ; GetSongName
  133.         gmodbra ntgetsongauthor         ; GetSongAuthor
  134.         gmodbra getfreqmodspeed         ; GetFrequency
  135.         gmodbra mt_music                ; TimerTick
  136.         gmodbra \makername              ; GetMakerName
  137.         gmodbra \hook                   ; Hook
  138.         gmodbra \jump
  139.         gmodnop
  140.         move.l  scroll(pc),d0
  141.         rts
  142.  
  143. \hook
  144.         move.l  #GMODHF_REPEAT!GMODHF_SEQUENCE,d0
  145.         rts
  146.  
  147. \makername
  148.         lea     name(pc),a0
  149.         move.l  a0,d0
  150.         rts
  151.  
  152. \jump
  153.         DISABLE a0
  154.         clr.w   mt_PatternPos
  155.         clr.b   mt_PBreakPos
  156.         clr.b   mt_PosJumpFlag
  157.         move.L  mt_SongDataPtr(PC),A0
  158.         suba.w  seqadj(pc),a0
  159.         moveq   #0,d0
  160.         move.b  $3b6(a0),d0
  161.         cmp.l   d0,d1
  162.         blo.s   \jumpok
  163.         cq      d1
  164. \jumpok
  165.         move.b  d1,mt_SongPos
  166.         exg     d1,d0
  167.         jsr     intsongpos
  168.         ENABLE  a0
  169.         moveq   #1,d1
  170.         rts
  171.  
  172.  
  173. n_note          EQU     0  ; W
  174. n_cmd           EQU     2  ; W
  175. n_cmdlo         EQU     3  ; B
  176. n_start         EQU     4  ; L
  177. n_length        EQU     8  ; W
  178. n_loopstart     EQU     10 ; L
  179. n_replen        EQU     14 ; W
  180. n_period        EQU     16 ; W
  181. n_finetune      EQU     18 ; B
  182. n_volume        EQU     19 ; B
  183. n_dmabit        EQU     20 ; W
  184. n_toneportdirec EQU     22 ; B
  185. n_toneportspeed EQU     23 ; B
  186. n_wantedperiod  EQU     24 ; W
  187. n_vibratocmd    EQU     26 ; B
  188. n_vibratopos    EQU     27 ; B
  189. n_tremolocmd    EQU     28 ; B
  190. n_tremolopos    EQU     29 ; B
  191. n_wavecontrol   EQU     30 ; B
  192. n_glissfunk     EQU     31 ; B
  193. n_sampleoffset  EQU     32 ; B
  194. n_pattpos       EQU     33 ; B
  195. n_loopcount     EQU     34 ; B
  196. n_funkoffset    EQU     35 ; B
  197. n_wavestart     EQU     36 ; L
  198. n_reallength    EQU     40 ; W
  199. n_channelno     EQU     42 ; W
  200. n_realper       EQU     44 ; W
  201. n_realvol       EQU     46 ; W
  202.  
  203. noteplayersave
  204.         move.l  a0,noteplayer
  205.         moveq   #1,d0
  206.         rts
  207.  
  208. init    movem.l d2-d3/a2-a3,-(sp)
  209.  
  210.         move.l  noteplayer(pc),a1       ; Initialize the NotePlayer
  211.         sub.l   a0,a0
  212.         moveq   #4,d0
  213.         jsr     NoteInit(a1)
  214.         tst.l   d0
  215.         bnz     initout
  216.  
  217.         clr.l   scroll
  218.  
  219.         move.l  modmem,a0               ;
  220.         MOVE.L  A0,mt_SongDataPtr
  221.         move.l  modend,a3
  222.         subq.l  #4,a3
  223.  
  224.         moveq   #0,d0                   ; Check for old modules
  225.         moveq   #0,d1
  226.         move.w  #31-1,-(sp)
  227.         tst.b   $1d6(a0)
  228.         beq.s   1$
  229.         cmp.b   #1,$1f3(a0)
  230.         beq.s   1$
  231.         cmp.l   #'M.K.',$438(a0)
  232.         beq.s   1$
  233.         move.w  #$1e0,d0
  234.         move.w  #$1e4,d1
  235.         move.w  #15-1,(sp)
  236. 1$      move.w  d0,seqadj
  237.         move.w  d1,blkadj
  238.  
  239.         MOVE.L  A0,A1
  240.         LEA     952(A1),A1
  241.         suba.w  d0,a1
  242.  
  243.         movem.l d0-d1/a0-a1,-(sp)       ; Set MultiPlayer's position display
  244.         moveq   #0,d0
  245.         moveq   #0,d1
  246.         move.b  -2(a1),d1
  247.         jsr     intsongpos
  248.         movem.l (sp)+,d0-d1/a0-a1
  249.  
  250.         MOVEQ   #127,D0
  251.         MOVEQ   #0,D1
  252. mtloop  MOVE.L  D1,D2
  253.         SUBQ.W  #1,D0
  254. mtloop2 MOVE.B  (A1)+,D1
  255.         CMP.B   D2,D1
  256.         BGT.S   mtloop
  257.         DBRA    D0,mtloop2
  258.         ADDQ.B  #1,D2
  259.  
  260.         LEA     mt_SampleStarts(PC),A1
  261.         ASL.L   #8,D2
  262.         ASL.L   #2,D2
  263.         ADD.L   #1084,D2
  264.         ADD.L   A0,D2
  265.         MOVE.L  D2,A2
  266.         suba.w  blkadj(pc),a2           ;
  267.         move.w  (sp)+,d0
  268. mtloop3
  269.  
  270. * Clear the first four bytes of the sample.  This piece of code has caused a great deal of grief for
  271. * many people before it included this end-of-module check.  (Just ask Ed Mackey. :-) )  Most
  272. * MutantTracker modules don't use all the available instrument slots, so the last instruments are
  273. * empty (zero length).  However, in unmodified player source code, this code keeps plowing on through,
  274. * clearing the first four bytes _past_ the end of the module.  This is usually no problem when the
  275. * module is part of a game or demo or something, but can cause weird memory errors when the module's
  276. * memory is allocated dynamically to its exact length.
  277. *
  278. * Oh yeah...Why clear the first four bytes?  Protracker and most other closely related mutants handle
  279. * non-repeating samples by simply setting the repeat position and length so that, after the sample is
  280. * played once, it plays the first four bytes over and over forever (until another sample is started).
  281. * If the first four bytes weren't zero, then you'd hear a weird buzzy sound at the end of any non-
  282. * repeating sample.
  283. *
  284. * Most new tracker modules come with the first four bytes of each sample already cleared, so this isn't
  285. * necessary for them.  It's mainly for older modules.
  286.  
  287.         cmp.l   a2,a3
  288.         blt.s   \inrange
  289.         clr.l   (a2)
  290. \inrange
  291.  
  292.         MOVE.L  A2,(A1)+
  293.         MOVEQ   #0,D1
  294.         MOVE.W  42(A0),D1
  295.         bz.b    \nosample
  296.  
  297. * This little hack is for old-style (15-instrument) modules that occasionally had 'repeat' stored as
  298. * number of bytes instead of words.  We assume that this is the case if repeat+replen > length.
  299. * This should be safe for all new modules, since repeat+replen is never supposed to be bigger than
  300. * the sample size.  However, it may not detect all cases of this syndrome, because repeat+replen
  301. * is allowed to be smaller (even much smaller) than the sample length (i.e. when some of the sample
  302. * is not used).
  303.         move.w  42+4(a0),d3
  304.         add.w   42+6(a0),d3
  305.         cmp.w   d1,d3
  306.         bls.b   \repeat_ok
  307.         lsr.w   42+4(a0)
  308. \repeat_ok
  309.  
  310.  
  311.         ASL.L   #1,D1
  312.         move.l  d1,d2
  313.         ADD.l   d1,a2
  314. \nosample
  315.  
  316.         ADD.L   #30,A0
  317.         DBRA    D0,mtloop3
  318.  
  319.         addq.l  #4,a3                   ; See if the last sample is a scrolltext
  320.         cmp.l   a2,a3
  321.         blt.b   \noscroll
  322.         move.l  d2,d0
  323.         cq      d1
  324. \more
  325.         tst.b   -(a2)
  326.         bpl.b   \lower
  327.         addq.l  #1,d1
  328. \lower
  329.         subq.l  #1,d0
  330.         bhi.b   \more
  331.  
  332.         lsl.l   #2,d1                   ; If 3/4 or more of the bytes are <$80, assume it's ASCII
  333.         cmp.l   d1,d2
  334.         blo.b   \noscroll
  335.  
  336.         clr.b   -1(a2,d2.l)             ; Null-terminate the scroll text
  337.         addq    #4,a2                   ; Get past the four bytes we clobbered
  338.         move.l  a2,scroll
  339. \noscroll
  340.  
  341.         moveq   #0,d0
  342. initout
  343.         movem.l (sp)+,d2-d3/a2-a3
  344.         rts
  345.  
  346. start
  347.         clr.w   scrollmod               ; Note scroller information
  348.  
  349.         moveq   #1,d0
  350.         bsr     initfilter
  351.  
  352.         clr.l   mt_chan1temp+n_realper
  353.         clr.l   mt_chan2temp+n_realper
  354.         clr.l   mt_chan3temp+n_realper
  355.         clr.l   mt_chan4temp+n_realper
  356.  
  357.         MOVE.B  #6,mt_speed
  358.         CLR.B   mt_counter
  359.         CLR.B   mt_SongPos
  360.         CLR.W   mt_PatternPos
  361.  
  362.         cq      d0
  363.         cq      d1
  364.         bsr     findnotetab
  365.  
  366.         st.b    playing
  367.         rts
  368.  
  369. mt_stop
  370.         clr.b   playing
  371.         rts
  372.  
  373. fin
  374.         move.l  noteplayer(pc),a0
  375.         jmp     NoteFinish(a0)
  376.  
  377. usevol  macro
  378.         cmp.w   n_realvol(a6),d0
  379.         beq.b   \usevol\@
  380.         movem.l d1-d2/d4/a0-a1,-(sp)
  381.         move.w  n_channelno(a6),d2
  382.         MOVE.W  D0,d4
  383.         move.w  d0,n_realvol(a6)
  384.         lsl.w   #2,d4
  385.         jsr     NoteVol(a5)
  386.         movem.l (sp)+,d1-d2/d4/a0-a1
  387. \usevol\@:
  388.         endm
  389.  
  390. useper  macro
  391.         cmp.w   n_realper(a6),d0
  392.         beq.b   \useper\@
  393.         movem.l d1-d3/a0-a1,-(sp)
  394.         move.w  n_channelno(a6),d2
  395.         moveq   #0,d3
  396.         move.w  d0,n_realper(a6)
  397.         MOVE.W  d0,d3
  398.         swap    d3
  399.         jsr     NoteFreq(a5)
  400.         movem.l (sp)+,d1-d3/a0-a1
  401. \useper\@
  402.         endm
  403.  
  404. * Register conventions:
  405. * d2 = Channel number (not quite yet)
  406. * d5-d7 = Always available
  407. * a5 = NotePlayer
  408. * a6 = chan#temp
  409.  
  410. mt_music
  411.         movem.l d0-d7/a0-a6,-(SP)            ;
  412.  
  413.         move.l  noteplayer(pc),a5
  414.  
  415.         ADDQ.B  #1,mt_counter
  416.         MOVE.B  mt_counter(PC),D0
  417.         CMP.B   mt_speed(PC),D0
  418.         BLO.S   mt_NoNewNote
  419.         CLR.B   mt_counter
  420.         TST.B   mt_PattDelTime2
  421.         BEQ.S   mt_GetNewNote
  422.         BSR.S   mt_NoNewAllChannels
  423.         BRA     mt_dskip
  424.  
  425. mt_NoNewNote
  426.         BSR.S   mt_NoNewAllChannels
  427.         BRA     mt_NoNewPosYet
  428.  
  429. mt_NoNewAllChannels
  430.         LEA     mt_chan1temp(PC),A6
  431.         BSR     mt_CheckEfx
  432.         LEA     mt_chan2temp(PC),A6
  433.         BSR     mt_CheckEfx
  434.         LEA     mt_chan3temp(PC),A6
  435.         BSR     mt_CheckEfx
  436.         LEA     mt_chan4temp(PC),A6
  437.         BRA     mt_CheckEfx
  438.  
  439. mt_GetNewNote
  440.         MOVE.L  mt_SongDataPtr(PC),A0
  441.         LEA     12(A0),A3
  442.         LEA     952(A0),A2      ;pattpo
  443.         suba.w  seqadj(pc),a2
  444.         LEA     1084(A0),A0     ;patterndata
  445.         suba.w  blkadj(pc),a0
  446.         MOVEQ   #0,D0
  447.         MOVEQ   #0,D1
  448.         MOVE.B  mt_SongPos(PC),D0
  449.         MOVE.B  0(A2,D0.W),D1
  450.         ASL.L   #8,D1
  451.         ASL.L   #2,D1
  452.         ADD.W   mt_PatternPos(PC),D1
  453.  
  454.         LEA     mt_chan1temp(PC),A6
  455.         BSR.S   mt_PlayVoice
  456.         LEA     mt_chan2temp(PC),A6
  457.         BSR.S   mt_PlayVoice
  458.         LEA     mt_chan3temp(PC),A6
  459.         BSR.S   mt_PlayVoice
  460.         LEA     mt_chan4temp(PC),A6
  461.         BSR.S   mt_PlayVoice
  462.         BRA     mt_SetDMA
  463.  
  464. mt_PlayVoice
  465.         TST.L   (A6)
  466.         BNE.S   mt_plvskip
  467.         BSR     mt_PerNop
  468. mt_plvskip
  469.         MOVE.L  0(A0,D1.L),(A6)
  470.         ADDQ.L  #4,D1
  471.         MOVEQ   #0,D2
  472.         MOVE.B  n_cmd(A6),D2
  473.         AND.B   #$F0,D2
  474.         LSR.B   #4,D2
  475.         MOVE.B  (A6),D0
  476.         AND.B   #$F0,D0
  477.         OR.B    D0,D2
  478.         BEQ     mt_SetRegs
  479.         MOVEQ   #0,D3
  480.         LEA     mt_SampleStarts(PC),A1
  481.         MOVE    D2,D4
  482.         SUBQ.L  #1,D2
  483.         ASL.L   #2,D2
  484.         MULU    #30,D4
  485.         MOVE.L  0(A1,D2.L),n_start(A6)
  486.         MOVE.W  0(A3,D4.L),n_length(A6)
  487.         MOVE.W  0(A3,D4.L),n_reallength(A6)
  488.         MOVE.B  2(A3,D4.L),n_finetune(A6)
  489.         MOVE.B  3(A3,D4.L),n_volume(A6)
  490.         MOVE.W  4(A3,D4.L),D3 ; Get repeat
  491.  
  492.         push    a0/d0-d3/a0        ; BAF - Flash the note on the display
  493.         move.w  (a6),d0
  494.         andi.w  #$fff,d0
  495.         lea     mt_PeriodTable(pc),a0
  496.         moveq   #-1,d1
  497. 1$      addq.w  #1,d1
  498.         cmp.w   (a0)+,d0
  499.         blo.b   1$
  500.         move.b  mt_FlashNotes(pc,d1.w),d1
  501.         move.w  n_channelno(a6),d0
  502.         move.b  n_volume(a6),d2
  503.         bsr     intflashnote
  504.  
  505.         move.l  n_start(a6),a0
  506.         move.w  (a6),d1
  507.         andi.w  #$fff,d1
  508.         move.w  n_length(a6),d2
  509.         add.w   d2,d2
  510.         move.w  6(a3,d4.l),d3
  511.         add.w   d3,d3
  512.         bsr     intflashsample
  513.         pop     a0/d0-d3/a0
  514.  
  515.         TST.W   D3
  516.         BEQ.S   mt_NoLoop
  517.         MOVE.L  n_start(A6),D2  ; Get start
  518.         ASL.W   #1,D3
  519.         ADD.L   D3,D2           ; Add repeat
  520.         MOVE.L  D2,n_loopstart(A6)
  521.         MOVE.L  D2,n_wavestart(A6)
  522.         MOVE.W  4(A3,D4.L),D0   ; Get repeat
  523.         ADD.W   6(A3,D4.L),D0   ; Add replen
  524.         MOVE.W  D0,n_length(A6)
  525.         MOVE.W  6(A3,D4.L),n_replen(A6) ; Save replen
  526.         BRA.S   mt_SetRegsVol
  527.  
  528. mt_FlashNotes   dc.b    0,7,14,21,28,35,42,49,56,64
  529.                 dc.b    71,78,85,92,99,106,113,120,128,135
  530.                 dc.b    142,149,156,163,170,177,184,192,199,206
  531.                 dc.b    213,220,227,234,241,248
  532.  
  533. mt_NoLoop
  534.         MOVE.L  n_start(A6),D2
  535.         MOVE.L  D2,n_loopstart(A6)
  536.         MOVE.L  D2,n_wavestart(A6)
  537.         MOVE.W  6(A3,D4.L),n_replen(A6) ; Save replen
  538. mt_SetRegsVol
  539.         MOVEQ   #0,D0
  540.         MOVE.B  n_volume(A6),D0
  541.         usevol
  542. mt_SetRegs
  543.         MOVE.W  (A6),D0
  544.         AND.W   #$0FFF,D0
  545.         BEQ     mt_CheckMoreEfx ; If no note
  546.         MOVE.W  2(A6),D0
  547.         AND.W   #$0FF0,D0
  548.         CMP.W   #$0E50,D0
  549.         BEQ.S   mt_DoSetFineTune
  550.         MOVE.B  2(A6),D0
  551.         AND.B   #$0F,D0
  552.         CMP.B   #3,D0   ; TonePortamento
  553.         BEQ.S   mt_ChkTonePorta
  554.         CMP.B   #5,D0
  555.         BEQ.S   mt_ChkTonePorta
  556.         CMP.B   #9,D0   ; Sample Offset
  557.         BNE.S   mt_SetPeriod
  558.         BSR     mt_CheckMoreEfx
  559.         BRA.S   mt_SetPeriod
  560.  
  561. mt_DoSetFineTune
  562.         BSR     mt_SetFineTune
  563.         BRA.S   mt_SetPeriod
  564.  
  565. mt_ChkTonePorta
  566.         BSR     mt_SetTonePorta
  567.         BRA     mt_CheckMoreEfx
  568.  
  569. mt_SetPeriod
  570.         MOVEM.L D0-D1/A0-A1,-(SP)
  571.         MOVE.W  (A6),D1
  572.         AND.W   #$0FFF,D1
  573.         tst.b   n_finetune(a6)
  574.         bz      mt_noft
  575.         LEA     mt_PeriodTable(PC),A1
  576.         MOVEQ   #0,D0
  577.         MOVEQ   #36,D2
  578. mt_ftuloop
  579.         CMP.W   0(A1,D0.W),D1
  580.         BHS.S   mt_ftufound
  581.         ADDQ.L  #2,D0
  582.         DBRA    D2,mt_ftuloop
  583. mt_ftufound
  584.         MOVEQ   #0,D1
  585.         MOVE.B  n_finetune(A6),D1
  586.         MULU    #36*2,D1
  587.         ADD.L   D1,A1
  588.         MOVE.W  0(A1,D0.W),d1
  589. mt_noft
  590.         move.w  d1,n_period(A6)
  591.         MOVEM.L (SP)+,D0-D1/A0-A1
  592.  
  593.         MOVE.W  2(A6),D0
  594.         AND.W   #$0FF0,D0
  595.         CMP.W   #$0ED0,D0 ; Notedelay
  596.         BEQ     mt_CheckMoreEfx
  597.  
  598.         BTST    #2,n_wavecontrol(A6)
  599.         BNE.S   mt_vibnoc
  600.         CLR.B   n_vibratopos(A6)
  601. mt_vibnoc
  602.         BTST    #6,n_wavecontrol(A6)
  603.         BNE.S   mt_trenoc
  604.         CLR.B   n_tremolopos(A6)
  605. mt_trenoc
  606.         movem.l d1-d4/a0-a1,-(sp)
  607.         move.l  n_start(a6),a0
  608.         moveq   #0,d0
  609.         move.w  n_length(a6),d0
  610.         add.l   d0,d0
  611.         move.l  n_loopstart(a6),a1
  612.         moveq   #0,d1
  613.         move.w  n_replen(a6),d1
  614.         cmp.w   #1,d1
  615.         bne.b   \notone
  616.         moveq   #0,d1
  617. \notone
  618.         add.l   d1,d1
  619.         move.w  n_channelno(a6),d2
  620.         moveq   #0,d3
  621.         move.w  n_period(a6),d3
  622.         move.w  d3,n_realper(a6)
  623.         swap    d3
  624.         moveq   #0,d4
  625.         move.b  n_volume(a6),d4
  626.         move.w  d4,n_realvol(a6)
  627.         lsl.w   #2,d4
  628.         jsr     NoteStart(a5)
  629.         movem.l (sp)+,d1-d4/a0-a1
  630.         BRA     mt_CheckMoreEfx
  631.  
  632. mt_SetDMA
  633.  
  634. mt_dskip
  635.         ADD.W   #16,mt_PatternPos
  636.         MOVE.B  mt_PattDelTime,D0
  637.         BEQ.S   mt_dskc
  638.         MOVE.B  D0,mt_PattDelTime2
  639.         CLR.B   mt_PattDelTime
  640. mt_dskc TST.B   mt_PattDelTime2
  641.         BEQ.S   mt_dska
  642.         SUBQ.B  #1,mt_PattDelTime2
  643.         BEQ.S   mt_dska
  644.         SUB.W   #16,mt_PatternPos
  645. mt_dska TST.B   mt_PBreakFlag
  646.         BEQ.S   mt_nnpysk
  647.         SF      mt_PBreakFlag
  648.         MOVEQ   #0,D0
  649.         MOVE.B  mt_PBreakPos(PC),D0
  650.         CLR.B   mt_PBreakPos
  651.         LSL.W   #4,D0
  652.         MOVE.W  D0,mt_PatternPos
  653. mt_nnpysk
  654.         CMP.W   #1024,mt_PatternPos
  655.         BLO.S   mt_NoNewBlock
  656. mt_NextPosition
  657.         MOVEQ   #0,D0
  658.         MOVE.B  mt_PBreakPos(PC),D0
  659.         LSL.W   #4,D0
  660.         MOVE.W  D0,mt_PatternPos
  661.         CLR.B   mt_PBreakPos
  662.         CLR.B   mt_PosJumpFlag
  663.         move.b  mt_SongPos(pc),d1       ; Fixes and opts
  664.         addq.B  #1,d1
  665.         and.B   #$7F,d1
  666.         move.L  mt_SongDataPtr(PC),A0
  667.         suba.w  seqadj(pc),a0
  668.         move.b  $3b6(a0),d2
  669.         cmp.b   d2,d1
  670.         blo.s   1$
  671.  
  672.         bsr     intrepeat               ; Signal when repeating
  673.  
  674.         move.b  $3b7(a0),d1
  675.         cmp.b   d2,d1                   ; < Fix - range check for song repeat
  676.         blo.s   1$
  677.         moveq   #0,d1
  678. 1$      move.b  d1,mt_SongPos
  679.  
  680.         moveq   #0,d0                   ; Update MultiPlayer's position display
  681.         move.b  d1,d0
  682.         moveq   #0,d1
  683.         move.b  d2,d1
  684.         jsr     intsongpos
  685.  
  686.         bsr.b   findnotetab
  687.  
  688. mt_NoNewBlock
  689.         move.w  mt_PatternPos(pc),d0    ; Update the scrolling note display
  690.         lsr.w   #4,d0
  691.         moveq   #64,d1
  692.         jsr     intflashscroll
  693.  
  694. mt_NoNewPosYet
  695.         TST.B   mt_PosJumpFlag
  696.         BNE     mt_NextPosition
  697.  
  698. mt_exit movem.l (sp)+,d0-d7/a0-a6
  699.         RTS
  700.  
  701.  
  702. findnotetab
  703.         MOVE.L  mt_SongDataPtr(PC),A0   ; Find the new note table
  704.         LEA     952(A0),A2
  705.         suba.w  seqadj(pc),a2
  706.         LEA     1084(A0),A0
  707.         suba.w  blkadj(pc),a0
  708.         MOVE.B  0(A2,D0.W),D1
  709.         ASL.L   #8,D1
  710.         ASL.L   #2,D1
  711.         add.l   d1,a0
  712.         move.l  a0,notetab
  713.         rts
  714.  
  715.  
  716. mt_CheckEfx
  717.         BSR     mt_UpdateFunk
  718.         MOVE.W  n_cmd(A6),D0
  719.         AND.W   #$0FFF,D0
  720.         BEQ.S   mt_PerNop
  721.         MOVE.B  n_cmd(A6),D0
  722.         AND.B   #$0F,D0
  723.         BEQ     mt_Arpeggio
  724.         CMP.B   #1,D0
  725.         BEQ     mt_PortaUp
  726.         CMP.B   #2,D0
  727.         BEQ     mt_PortaDown
  728.         CMP.B   #3,D0
  729.         BEQ     mt_TonePortamento
  730.         CMP.B   #4,D0
  731.         BEQ     mt_Vibrato
  732.         CMP.B   #5,D0
  733.         BEQ     mt_TonePlusVolSlide
  734.         CMP.B   #6,D0
  735.         BEQ     mt_VibratoPlusVolSlide
  736.         CMP.B   #$E,D0
  737.         BEQ     mt_E_Commands
  738. SetBack move.w  d0,-(sp)
  739.         move.w  n_period(a6),d0
  740.         useper
  741.         move.w  (sp)+,d0
  742.         CMP.B   #7,D0
  743.         BEQ     mt_Tremolo
  744.         CMP.B   #$A,D0
  745.         BEQ     mt_VolumeSlide
  746. mt_Return2
  747.         RTS
  748.  
  749. mt_PerNop
  750.         move.w  n_period(a6),d0
  751.         useper
  752.         RTS
  753.  
  754.  
  755. *** mt_Arpeggio - Process arpeggio commands (off-cycles)
  756. mt_Arpeggio
  757.         MOVEQ   #0,D7
  758.         MOVE.B  mt_counter(PC),D7
  759.         divu.w  #3,D7
  760.         swap    d7
  761.         subq.w  #1,d7
  762.         blo.s   \mt_Arpeggio2
  763.         bhi.S   \mt_Arpeggio1
  764.         MOVE.B  n_cmdlo(A6),D7
  765.         LSR.B   #4,D7
  766.         BRA.S   \mt_Arpeggio3
  767.  
  768. \mt_Arpeggio1
  769.         MOVE.B  n_cmdlo(A6),D7
  770.         AND.w   #$f,D7
  771.         BRA.S   \mt_Arpeggio3
  772.  
  773. \mt_Arpeggio2
  774.         MOVE.W  n_period(A6),D0
  775.         BRA.S   \mt_Arpeggio4
  776.  
  777. \mt_Arpeggio3
  778.         add.w   d7,d7
  779.         MOVEQ   #0,D1
  780.         MOVE.B  n_finetune(A6),D1
  781.         MULU    #36*2,D1
  782.         LEA     mt_PeriodTable(PC),A0
  783.         ADD.w   D1,A0
  784.         MOVEQ   #0,D1
  785.         MOVE.W  n_period(A6),D1
  786.         MOVEQ   #36,D6
  787. \mt_arploop
  788.         CMP.W   (A0)+,D1
  789.         BHS.S   \mt_Arpeggio4a
  790.         DBRA    D6,\mt_arploop
  791.         RTS
  792.  
  793. \mt_Arpeggio4a
  794.         MOVE.W  -2(A0,D7.W),D0
  795. \mt_Arpeggio4
  796.         useper
  797.         RTS
  798.  
  799.  
  800.  
  801. mt_FinePortaUp
  802.         TST.B   mt_counter
  803.         BNE     mt_Return2
  804.         MOVE.B  #$0F,mt_LowMask
  805. mt_PortaUp
  806.         MOVEQ   #0,D0
  807.         MOVE.B  n_cmdlo(A6),D0
  808.         AND.B   mt_LowMask(PC),D0
  809.         MOVE.B  #$FF,mt_LowMask
  810.         SUB.W   D0,n_period(A6)
  811.         MOVE.W  n_period(A6),D0
  812.         AND.W   #$0FFF,D0
  813.         CMP.W   #113,D0
  814.         BPL.S   mt_PortaUskip
  815.         AND.W   #$F000,n_period(A6)
  816.         OR.W    #113,n_period(A6)
  817. mt_PortaUskip
  818.         MOVE.W  n_period(A6),D0
  819.         AND.W   #$0FFF,D0
  820.         useper
  821.         RTS
  822.  
  823.  
  824.  
  825. mt_FinePortaDown
  826.         TST.B   mt_counter
  827.         BNE     mt_Return2
  828.         MOVE.B  #$0F,mt_LowMask
  829. mt_PortaDown
  830.         CLR.W   D0
  831.         MOVE.B  n_cmdlo(A6),D0
  832.         AND.B   mt_LowMask(PC),D0
  833.         MOVE.B  #$FF,mt_LowMask
  834.         ADD.W   D0,n_period(A6)
  835.         MOVE.W  n_period(A6),D0
  836.         AND.W   #$0FFF,D0
  837.         CMP.W   #856,D0
  838.         BMI.S   mt_PortaDskip
  839.         AND.W   #$F000,n_period(A6)
  840.         OR.W    #856,n_period(A6)
  841. mt_PortaDskip
  842.         MOVE.W  n_period(A6),D0
  843.         AND.W   #$0FFF,D0
  844.         useper
  845.         RTS
  846.  
  847. mt_SetTonePorta
  848.         MOVE.L  A0,-(SP)
  849.         MOVE.W  (A6),D2
  850.         AND.W   #$0FFF,D2
  851.         MOVEQ   #0,D0
  852.         MOVE.B  n_finetune(A6),D0
  853.         MULU    #36*2,D0
  854.         LEA     mt_PeriodTable(PC),A0
  855.         ADD.L   D0,A0
  856.         MOVEQ   #0,D0
  857. mt_StpLoop
  858.         CMP.W   0(A0,D0.W),D2
  859.         BHS.S   mt_StpFound
  860.         ADDQ.W  #2,D0
  861.         CMP.W   #36*2,D0
  862.         BLO.S   mt_StpLoop
  863.         MOVEQ   #35*2,D0
  864. mt_StpFound
  865.         MOVE.B  n_finetune(A6),D2
  866.         AND.B   #8,D2
  867.         BEQ.S   mt_StpGoss
  868.         TST.W   D0
  869.         BEQ.S   mt_StpGoss
  870.         SUBQ.W  #2,D0
  871. mt_StpGoss
  872.         MOVE.W  0(A0,D0.W),D2
  873.         MOVE.L  (SP)+,A0
  874.         MOVE.W  D2,n_wantedperiod(A6)
  875.         MOVE.W  n_period(A6),D0
  876.         CLR.B   n_toneportdirec(A6)
  877.         CMP.W   D0,D2
  878.         BEQ.S   mt_ClearTonePorta
  879.         BGE     mt_Return2
  880.         MOVE.B  #1,n_toneportdirec(A6)
  881.         RTS
  882.  
  883. mt_ClearTonePorta
  884.         CLR.W   n_wantedperiod(A6)
  885.         RTS
  886.  
  887. mt_TonePortamento
  888.         MOVE.B  n_cmdlo(A6),D0
  889.         BEQ.S   mt_TonePortNoChange
  890.         MOVE.B  D0,n_toneportspeed(A6)
  891.         CLR.B   n_cmdlo(A6)
  892. mt_TonePortNoChange
  893.         TST.W   n_wantedperiod(A6)
  894.         BEQ     mt_Return2
  895.         MOVEQ   #0,D0
  896.         MOVE.B  n_toneportspeed(A6),D0
  897.         TST.B   n_toneportdirec(A6)
  898.         BNE.S   mt_TonePortaUp
  899. mt_TonePortaDown
  900.         ADD.W   D0,n_period(A6)
  901.         MOVE.W  n_wantedperiod(A6),D0
  902.         CMP.W   n_period(A6),D0
  903.         BGT.S   mt_TonePortaSetPer
  904.         MOVE.W  n_wantedperiod(A6),n_period(A6)
  905.         CLR.W   n_wantedperiod(A6)
  906.         BRA.S   mt_TonePortaSetPer
  907.  
  908. mt_TonePortaUp
  909.         SUB.W   D0,n_period(A6)
  910.         MOVE.W  n_wantedperiod(A6),D0
  911.         CMP.W   n_period(A6),D0
  912.         BLT.S   mt_TonePortaSetPer
  913.         MOVE.W  n_wantedperiod(A6),n_period(A6)
  914.         CLR.W   n_wantedperiod(A6)
  915.  
  916. mt_TonePortaSetPer
  917.         MOVE.W  n_period(A6),D2
  918.         MOVE.B  n_glissfunk(A6),D0
  919.         AND.B   #$0F,D0
  920.         BEQ.S   mt_GlissSkip
  921.         MOVEQ   #0,D0
  922.         MOVE.B  n_finetune(A6),D0
  923.         MULU    #36*2,D0
  924.         LEA     mt_PeriodTable(PC),A0
  925.         ADD.L   D0,A0
  926.         MOVEQ   #0,D0
  927. mt_GlissLoop
  928.         CMP.W   0(A0,D0.W),D2
  929.         BHS.S   mt_GlissFound
  930.         ADDQ.W  #2,D0
  931.         CMP.W   #36*2,D0
  932.         BLO.S   mt_GlissLoop
  933.         MOVEQ   #35*2,D0
  934. mt_GlissFound
  935.         MOVE.W  0(A0,D0.W),D2
  936. mt_GlissSkip
  937.         move.w  d2,d0
  938.         useper
  939.         RTS
  940.  
  941. mt_Vibrato
  942.         MOVE.B  n_cmdlo(A6),D0
  943.         BEQ.S   mt_Vibrato2
  944.         MOVE.B  n_vibratocmd(A6),D2
  945.         AND.B   #$0F,D0
  946.         BEQ.S   mt_vibskip
  947.         AND.B   #$F0,D2
  948.         OR.B    D0,D2
  949. mt_vibskip
  950.         MOVE.B  n_cmdlo(A6),D0
  951.         AND.B   #$F0,D0
  952.         BEQ.S   mt_vibskip2
  953.         AND.B   #$0F,D2
  954.         OR.B    D0,D2
  955. mt_vibskip2
  956.         MOVE.B  D2,n_vibratocmd(A6)
  957. mt_Vibrato2
  958.         MOVE.B  n_vibratopos(A6),D0
  959.         LEA     mt_VibratoTable(PC),A4
  960.         LSR.W   #2,D0
  961.         AND.W   #$001F,D0
  962.         MOVEQ   #0,D2
  963.         MOVE.B  n_wavecontrol(A6),D2
  964.         AND.B   #$03,D2
  965.         BEQ.S   mt_vib_sine
  966.         LSL.B   #3,D0
  967.         CMP.B   #1,D2
  968.         BEQ.S   mt_vib_rampdown
  969.         MOVE.B  #255,D2
  970.         BRA.S   mt_vib_set
  971. mt_vib_rampdown
  972.         TST.B   n_vibratopos(A6)
  973.         BPL.S   mt_vib_rampdown2
  974.         MOVE.B  #255,D2
  975.         SUB.B   D0,D2
  976.         BRA.S   mt_vib_set
  977. mt_vib_rampdown2
  978.         MOVE.B  D0,D2
  979.         BRA.S   mt_vib_set
  980. mt_vib_sine
  981.         MOVE.B  0(A4,D0.W),D2
  982. mt_vib_set
  983.         MOVE.B  n_vibratocmd(A6),D0
  984.         AND.W   #15,D0
  985.         MULU    D0,D2
  986.         LSR.W   #7,D2
  987.         MOVE.W  n_period(A6),D0
  988.         TST.B   n_vibratopos(A6)
  989.         BMI.S   mt_VibratoNeg
  990.         ADD.W   D2,D0
  991.         BRA.S   mt_Vibrato3
  992. mt_VibratoNeg
  993.         SUB.W   D2,D0
  994. mt_Vibrato3
  995.         useper
  996.         MOVE.B  n_vibratocmd(A6),D0
  997.         LSR.W   #2,D0
  998.         AND.W   #$003C,D0
  999.         ADD.B   D0,n_vibratopos(A6)
  1000.         RTS
  1001.  
  1002. mt_TonePlusVolSlide
  1003.         BSR     mt_TonePortNoChange
  1004.         BRA     mt_VolumeSlide
  1005.  
  1006. mt_VibratoPlusVolSlide
  1007.         BSR     mt_Vibrato2
  1008.         BRA     mt_VolumeSlide
  1009.  
  1010. mt_Tremolo
  1011.         MOVE.B  n_cmdlo(A6),D0
  1012.         BEQ.S   mt_Tremolo2
  1013.         MOVE.B  n_tremolocmd(A6),D2
  1014.         AND.B   #$0F,D0
  1015.         BEQ.S   mt_treskip
  1016.         AND.B   #$F0,D2
  1017.         OR.B    D0,D2
  1018. mt_treskip
  1019.         MOVE.B  n_cmdlo(A6),D0
  1020.         AND.B   #$F0,D0
  1021.         BEQ.S   mt_treskip2
  1022.         AND.B   #$0F,D2
  1023.         OR.B    D0,D2
  1024. mt_treskip2
  1025.         MOVE.B  D2,n_tremolocmd(A6)
  1026. mt_Tremolo2
  1027.         MOVE.B  n_tremolopos(A6),D0
  1028.         LEA     mt_VibratoTable(PC),A4
  1029.         LSR.W   #2,D0
  1030.         AND.W   #$001F,D0
  1031.         MOVEQ   #0,D2
  1032.         MOVE.B  n_wavecontrol(A6),D2
  1033.         LSR.B   #4,D2
  1034.         AND.B   #$03,D2
  1035.         BEQ.S   mt_tre_sine
  1036.         LSL.B   #3,D0
  1037.         CMP.B   #1,D2
  1038.         BEQ.S   mt_tre_rampdown
  1039.         MOVE.B  #255,D2
  1040.         BRA.S   mt_tre_set
  1041. mt_tre_rampdown
  1042.         TST.B   n_vibratopos(A6)
  1043.         BPL.S   mt_tre_rampdown2
  1044.         MOVE.B  #255,D2
  1045.         SUB.B   D0,D2
  1046.         BRA.S   mt_tre_set
  1047. mt_tre_rampdown2
  1048.         MOVE.B  D0,D2
  1049.         BRA.S   mt_tre_set
  1050. mt_tre_sine
  1051.         MOVE.B  0(A4,D0.W),D2
  1052. mt_tre_set
  1053.         MOVE.B  n_tremolocmd(A6),D0
  1054.         AND.W   #15,D0
  1055.         MULU    D0,D2
  1056.         LSR.W   #6,D2
  1057.         MOVEQ   #0,D0
  1058.         MOVE.B  n_volume(A6),D0
  1059.         TST.B   n_tremolopos(A6)
  1060.         BMI.S   mt_TremoloNeg
  1061.         ADD.W   D2,D0
  1062.         BRA.S   mt_Tremolo3
  1063. mt_TremoloNeg
  1064.         SUB.W   D2,D0
  1065. mt_Tremolo3
  1066.         BPL.S   mt_TremoloSkip
  1067.         CLR.W   D0
  1068. mt_TremoloSkip
  1069.         CMP.W   #$40,D0
  1070.         BLS.S   mt_TremoloOk
  1071.         MOVE.W  #$40,D0
  1072. mt_TremoloOk
  1073.         usevol
  1074.         MOVE.B  n_tremolocmd(A6),D0
  1075.         LSR.W   #2,D0
  1076.         AND.W   #$003C,D0
  1077.         ADD.B   D0,n_tremolopos(A6)
  1078.         RTS
  1079.  
  1080. mt_SampleOffset
  1081.         MOVEQ   #0,D0
  1082.         MOVE.B  n_cmdlo(A6),D0
  1083.         BEQ.S   mt_sononew
  1084.         MOVE.B  D0,n_sampleoffset(A6)
  1085. mt_sononew
  1086.         MOVE.B  n_sampleoffset(A6),D0
  1087.         LSL.W   #7,D0
  1088.         CMP.W   n_length(A6),D0
  1089.         BGE.S   mt_sofskip
  1090.         SUB.W   D0,n_length(A6)
  1091.         LSL.W   #1,D0
  1092.         ADD.L   D0,n_start(A6)
  1093.         RTS
  1094. mt_sofskip
  1095.         MOVE.W  #$0001,n_length(A6)
  1096.         RTS
  1097.  
  1098.  
  1099.  
  1100. *** mt_VolumeSlide ($A), mt_VolumeFineUp ($EA), mt_VolumeFineDown ($EB)
  1101. mt_VolumeSlide
  1102.         MOVEQ   #0,D0
  1103.         MOVE.B  n_cmdlo(A6),D0
  1104.         LSR.B   #4,D0
  1105.         BEQ.S   vol_VolSlideDown
  1106.  
  1107. vol_VolSlideUp
  1108.         ADD.B   n_volume(A6),d0
  1109.         CMP.B   #$40,d0
  1110.         bls.S   \mt_vsuskip
  1111.         moveq   #$40,d0
  1112. \mt_vsuskip
  1113.         MOVE.B  d0,n_volume(A6)
  1114.         bra     vol_set
  1115.  
  1116. mt_VolumeFineUp
  1117.         TST.B   mt_counter
  1118.         BNE     mt_Return2
  1119.         MOVE.B  n_cmdlo(A6),D0
  1120.         and.w   #$F,D0
  1121.         BRA     vol_VolSlideUp
  1122.  
  1123. vol_VolSlideDown
  1124.         MOVE.B  n_cmdlo(A6),D0
  1125.         AND.w   #$0F,D0
  1126. vol_VolSlideDown2
  1127.         SUB.B   D0,n_volume(A6)
  1128.         bhs.S   \mt_vsdskip
  1129.         CLR.B   n_volume(A6)
  1130. \mt_vsdskip
  1131.  
  1132.         MOVE.B  n_volume(A6),d0
  1133. vol_set
  1134.         usevol
  1135.         RTS
  1136.  
  1137. mt_VolumeFineDown
  1138.         TST.B   mt_counter
  1139.         BNE     mt_Return2
  1140.         MOVE.B  n_cmdlo(A6),D0
  1141.         AND.w   #$0F,D0
  1142.         BRA     vol_VolSlideDown2
  1143.  
  1144.  
  1145.  
  1146. mt_PositionJump
  1147.         MOVE.B  n_cmdlo(A6),D0
  1148.  
  1149.         cmp.b   mt_SongPos(pc),d0       ; Check for repeat
  1150.         bhi.s   1$
  1151.         jsr     intrepeat
  1152. 1$
  1153.         SUBQ.B  #1,D0
  1154.         MOVE.B  D0,mt_SongPos
  1155. mt_pj2  CLR.B   mt_PBreakPos
  1156.         ST      mt_PosJumpFlag
  1157.         RTS
  1158.  
  1159.  
  1160. *** mt_VolumeChange - Effect $C, on-cycles
  1161. mt_VolumeChange
  1162.         MOVEQ   #0,D0
  1163.         MOVE.B  n_cmdlo(A6),D0
  1164.         CMP.B   #$40,D0
  1165.         BLS.S   \mt_VolumeOk
  1166.         MOVEQ   #$40,D0
  1167. \mt_VolumeOk
  1168.         MOVE.B  D0,n_volume(A6)
  1169.         usevol
  1170.         RTS
  1171.  
  1172.  
  1173. mt_PatternBreak
  1174.         MOVEQ   #0,D0
  1175.         MOVE.B  n_cmdlo(A6),D0
  1176.         MOVE.L  D0,D2
  1177.         LSR.B   #4,D0
  1178.         MULU    #10,D0
  1179.         AND.B   #$0F,D2
  1180.         ADD.B   D2,D0
  1181.         CMP.B   #63,D0
  1182.         BHI.S   mt_pj2
  1183.         MOVE.B  D0,mt_PBreakPos
  1184.         ST      mt_PosJumpFlag
  1185.         RTS
  1186.  
  1187. mt_SetSpeed
  1188.         MOVEQ   #0,D0
  1189.         MOVE.B  3(A6),D0
  1190.         BEQ     \out
  1191.         CMP.B   #$20,D0
  1192.         blo.b   \normal
  1193.         btst.b  #MNB_PTTEMPO,modflags
  1194.         bnz     SetTempo
  1195. \normal
  1196.         CLR.B   mt_counter
  1197.         MOVE.B  D0,mt_speed
  1198. \out
  1199.         RTS
  1200.  
  1201.  
  1202. mt_CheckMoreEfx
  1203.         BSR     mt_UpdateFunk
  1204.         MOVE.B  2(A6),D0
  1205.         AND.B   #$0F,D0
  1206.         CMP.B   #$9,D0
  1207.         BEQ     mt_SampleOffset
  1208.         CMP.B   #$B,D0
  1209.         BEQ     mt_PositionJump
  1210.         CMP.B   #$D,D0
  1211.         BEQ     mt_PatternBreak
  1212.         CMP.B   #$E,D0
  1213.         BEQ.S   mt_E_Commands
  1214.         CMP.B   #$F,D0
  1215.         BEQ.S   mt_SetSpeed
  1216.         CMP.B   #$C,D0
  1217.         BEQ     mt_VolumeChange
  1218.         BRA     mt_PerNop
  1219.  
  1220. mt_E_Commands
  1221.         MOVE.B  n_cmdlo(A6),D0
  1222.         AND.B   #$F0,D0
  1223.         LSR.B   #4,D0
  1224.         BEQ.S   mt_FilterOnOff
  1225.         CMP.B   #1,D0
  1226.         BEQ     mt_FinePortaUp
  1227.         CMP.B   #2,D0
  1228.         BEQ     mt_FinePortaDown
  1229.         CMP.B   #3,D0
  1230.         BEQ     mt_SetGlissControl
  1231.         CMP.B   #4,D0
  1232.         BEQ     mt_SetVibratoControl
  1233.         CMP.B   #5,D0
  1234.         BEQ     mt_SetFineTune
  1235.         CMP.B   #6,D0
  1236.         BEQ     mt_JumpLoop
  1237.         CMP.B   #7,D0
  1238.         BEQ     mt_SetTremoloControl
  1239.         CMP.B   #9,D0
  1240.         BEQ     mt_RetrigNote
  1241.         CMP.B   #$A,D0
  1242.         BEQ     mt_VolumeFineUp
  1243.         CMP.B   #$B,D0
  1244.         BEQ     mt_VolumeFineDown
  1245.         CMP.B   #$C,D0
  1246.         BEQ     mt_NoteCut
  1247.         CMP.B   #$D,D0
  1248.         BEQ     mt_NoteDelay
  1249.         CMP.B   #$E,D0
  1250.         BEQ     mt_PatternDelay
  1251.         CMP.B   #$F,D0
  1252.         BEQ     mt_FunkIt
  1253.         RTS
  1254.  
  1255. mt_FilterOnOff
  1256.         MOVE.B  n_cmdlo(A6),D0
  1257.         AND.B   #1,D0
  1258. initfilter
  1259.         move.b  d0,modfilter
  1260. setfilter
  1261.         tst.b   filter
  1262.         ble.b   \modcontrol
  1263.         moveq   #2,d0
  1264.         sub.b   filter,d0
  1265. \modcontrol
  1266.         add.b   d0,d0
  1267.         and.b   #2,d0
  1268.         AND.B   #$FD,$BFE001
  1269.         OR.B    D0,$BFE001
  1270.         RTS
  1271.  
  1272. ptfilter
  1273.         tst.b   playing
  1274.         bz      mt_Return2
  1275.         move.b  modfilter(pc),d0
  1276.         bra.b   setfilter
  1277.  
  1278.  
  1279. mt_SetGlissControl
  1280.         MOVE.B  n_cmdlo(A6),D0
  1281.         AND.B   #$0F,D0
  1282.         AND.B   #$F0,n_glissfunk(A6)
  1283.         OR.B    D0,n_glissfunk(A6)
  1284.         RTS
  1285.  
  1286.  
  1287. mt_SetVibratoControl
  1288.         MOVE.B  n_cmdlo(A6),D0
  1289.         AND.B   #$0F,D0
  1290.         AND.B   #$F0,n_wavecontrol(A6)
  1291.         OR.B    D0,n_wavecontrol(A6)
  1292.         RTS
  1293.  
  1294.  
  1295. mt_SetFineTune
  1296.         MOVE.B  n_cmdlo(A6),D0
  1297.         AND.B   #$0F,D0
  1298.         MOVE.B  D0,n_finetune(A6)
  1299.         RTS
  1300.  
  1301.  
  1302. mt_JumpLoop
  1303.         TST.B   mt_counter
  1304.         BNE     mt_Return2
  1305.         MOVE.B  n_cmdlo(A6),D0
  1306.         AND.B   #$0F,D0
  1307.         BEQ.S   mt_SetLoop
  1308.         TST.B   n_loopcount(A6)
  1309.         BEQ.S   mt_jumpcnt
  1310.         SUBQ.B  #1,n_loopcount(A6)
  1311.         BEQ     mt_Return2
  1312. mt_jmploop
  1313.         MOVE.B  n_pattpos(A6),mt_PBreakPos
  1314.         ST      mt_PBreakFlag
  1315.         RTS
  1316.  
  1317. mt_jumpcnt
  1318.         MOVE.B  D0,n_loopcount(A6)
  1319.         BRA.S   mt_jmploop
  1320.  
  1321. mt_SetLoop
  1322.         MOVE.W  mt_PatternPos(PC),D0
  1323.         LSR.W   #4,D0
  1324.         MOVE.B  D0,n_pattpos(A6)
  1325.         RTS
  1326.  
  1327. mt_SetTremoloControl
  1328.         MOVE.B  n_cmdlo(A6),D0
  1329.         AND.B   #$0F,D0
  1330.         LSL.B   #4,D0
  1331.         AND.B   #$0F,n_wavecontrol(A6)
  1332.         OR.B    D0,n_wavecontrol(A6)
  1333.         RTS
  1334.  
  1335. mt_RetrigNote
  1336.         MOVE.L  D1,-(SP)
  1337.         MOVEQ   #0,D0
  1338.         MOVE.B  n_cmdlo(A6),D0
  1339.         AND.B   #$0F,D0
  1340.         BEQ.S   mt_rtnend
  1341.         MOVEQ   #0,D1
  1342.         MOVE.B  mt_counter(PC),D1
  1343.         BNE.S   mt_rtnskp
  1344.         MOVE.W  (A6),D1
  1345.         AND.W   #$0FFF,D1
  1346.         BNE.S   mt_rtnend
  1347.         MOVEQ   #0,D1
  1348.         MOVE.B  mt_counter(PC),D1
  1349. mt_rtnskp
  1350.         DIVU    D0,D1
  1351.         SWAP    D1
  1352.         TST.W   D1
  1353.         BNE.S   mt_rtnend
  1354. mt_DoRetrig
  1355.         movem.l d2-d4/a0-a1,-(sp)
  1356.         move.l  n_start(a6),a0
  1357.         moveq   #0,d0
  1358.         move.w  n_length(a6),d0
  1359.         add.l   d0,d0
  1360.         move.l  n_loopstart(a6),a1
  1361.         moveq   #0,d1
  1362.         move.w  n_replen(a6),d1
  1363.         cmp.w   #1,d1
  1364.         bne.b   \notone
  1365.         moveq   #0,d1
  1366. \notone
  1367.         add.l   d1,d1
  1368.         move.w  n_channelno(a6),d2
  1369.         moveq   #0,d3
  1370.         move.w  n_period(a6),d3
  1371.         move.w  d3,n_realper(a6)
  1372.         swap    d3
  1373.         moveq   #0,d4
  1374.         move.b  n_volume(a6),d4
  1375.         move.w  d4,n_realvol(a6)
  1376.         lsl.w   #2,d4
  1377.         jsr     NoteStart(a5)
  1378.         movem.l (sp)+,d2-d4/a0-a1
  1379. mt_rtnend
  1380.         MOVE.L  (SP)+,D1
  1381.         RTS
  1382.  
  1383.  
  1384. mt_NoteCut
  1385.         MOVEQ   #0,D0
  1386.         MOVE.B  n_cmdlo(A6),D0
  1387.         AND.B   #$0F,D0
  1388.         CMP.B   mt_counter(PC),D0
  1389.         BNE     mt_Return2
  1390.         CLR.B   n_volume(A6)
  1391.         moveq   #0,d0
  1392.         usevol
  1393.         RTS
  1394.  
  1395. mt_NoteDelay
  1396.         MOVEQ   #0,D0
  1397.         MOVE.B  n_cmdlo(A6),D0
  1398.         AND.B   #$0F,D0
  1399.         CMP.B   mt_counter,D0
  1400.         BNE     mt_Return2
  1401.         MOVE.W  (A6),D0
  1402.         BEQ     mt_Return2
  1403.         MOVE.L  D1,-(SP)
  1404.         BRA     mt_DoRetrig
  1405.  
  1406. mt_PatternDelay
  1407.         TST.B   mt_counter
  1408.         BNE     mt_Return2
  1409.         MOVEQ   #0,D0
  1410.         MOVE.B  n_cmdlo(A6),D0
  1411.         AND.B   #$0F,D0
  1412.         TST.B   mt_PattDelTime2
  1413.         BNE     mt_Return2
  1414.         ADDQ.B  #1,D0
  1415.         MOVE.B  D0,mt_PattDelTime
  1416.         RTS
  1417.  
  1418. mt_FunkIt
  1419.         TST.B   mt_counter
  1420.         BNE     mt_Return2
  1421.         MOVE.B  n_cmdlo(A6),D0
  1422.         AND.B   #$0F,D0
  1423.         LSL.B   #4,D0
  1424.         AND.B   #$0F,n_glissfunk(A6)
  1425.         OR.B    D0,n_glissfunk(A6)
  1426.         TST.B   D0
  1427.         BEQ     mt_Return2
  1428. mt_UpdateFunk
  1429.         MOVEM.L D1/A0,-(SP)
  1430.         MOVEQ   #0,D0
  1431.         MOVE.B  n_glissfunk(A6),D0
  1432.         LSR.B   #4,D0
  1433.         BEQ.S   mt_funkend
  1434.         LEA     mt_FunkTable(PC),A0
  1435.         MOVE.B  0(A0,D0.W),D0
  1436.         ADD.B   D0,n_funkoffset(A6)
  1437.         BTST    #7,n_funkoffset(A6)
  1438.         BEQ.S   mt_funkend
  1439.         CLR.B   n_funkoffset(A6)
  1440.  
  1441.         MOVE.L  n_loopstart(A6),D0
  1442.         MOVEQ   #0,D1
  1443.         MOVE.W  n_replen(A6),D1
  1444.         ADD.L   D1,D0
  1445.         ADD.L   D1,D0
  1446.         MOVE.L  n_wavestart(A6),A0
  1447.         ADDQ.L  #1,A0
  1448.         CMP.L   D0,A0
  1449.         BLO.S   mt_funkok
  1450.         MOVE.L  n_loopstart(A6),A0
  1451. mt_funkok
  1452.         MOVE.L  A0,n_wavestart(A6)
  1453.         MOVEQ   #-1,D0
  1454.         SUB.B   (A0),D0
  1455.         MOVE.B  D0,(A0)
  1456. mt_funkend
  1457.         MOVEM.L (SP)+,D1/A0
  1458.         RTS
  1459.  
  1460.  
  1461. SetTempo
  1462.         push    a0/d0/d1
  1463.         move.w  d0,d1
  1464.         move.l  4,a0
  1465.         move.l  #1789773,d0
  1466.         cmp.b   #50,PowerSupplyFrequency(a0)
  1467.         bne.s   2$
  1468.         move.l  #1773447,d0
  1469. 2$      divu.w  d1,d0
  1470.         bsr     changetintcia
  1471.         pop     a0/d0/d1
  1472.         rts
  1473.  
  1474.  
  1475. mt_FunkTable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128
  1476.  
  1477. mt_VibratoTable
  1478.         dc.b   0,24,49,74,97,120,141,161
  1479.         dc.b 180,197,212,224,235,244,250,253
  1480.         dc.b 255,253,250,244,235,224,212,197
  1481.         dc.b 180,161,141,120,97,74,49,24
  1482.  
  1483. mt_PeriodTable
  1484. ; Tuning 0, Normal
  1485.         dc.w    856,808,762,720,678,640,604,570,538,508,480,453
  1486.         dc.w    428,404,381,360,339,320,302,285,269,254,240,226
  1487.         dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  1488. ; Tuning 1
  1489.         dc.w    850,802,757,715,674,637,601,567,535,505,477,450
  1490.         dc.w    425,401,379,357,337,318,300,284,268,253,239,225
  1491.         dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  1492. ; Tuning 2
  1493.         dc.w    844,796,752,709,670,632,597,563,532,502,474,447
  1494.         dc.w    422,398,376,355,335,316,298,282,266,251,237,224
  1495.         dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  1496. ; Tuning 3
  1497.         dc.w    838,791,746,704,665,628,592,559,528,498,470,444
  1498.         dc.w    419,395,373,352,332,314,296,280,264,249,235,222
  1499.         dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  1500. ; Tuning 4
  1501.         dc.w    832,785,741,699,660,623,588,555,524,495,467,441
  1502.         dc.w    416,392,370,350,330,312,294,278,262,247,233,220
  1503.         dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  1504. ; Tuning 5
  1505.         dc.w    826,779,736,694,655,619,584,551,520,491,463,437
  1506.         dc.w    413,390,368,347,328,309,292,276,260,245,232,219
  1507.         dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  1508. ; Tuning 6
  1509.         dc.w    820,774,730,689,651,614,580,547,516,487,460,434
  1510.         dc.w    410,387,365,345,325,307,290,274,258,244,230,217
  1511.         dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  1512. ; Tuning 7
  1513.         dc.w    814,768,725,684,646,610,575,543,513,484,457,431
  1514.         dc.w    407,384,363,342,323,305,288,272,256,242,228,216
  1515.         dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  1516. ; Tuning -8
  1517.         dc.w    907,856,808,762,720,678,640,604,570,538,508,480
  1518.         dc.w    453,428,404,381,360,339,320,302,285,269,254,240
  1519.         dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  1520. ; Tuning -7
  1521.         dc.w    900,850,802,757,715,675,636,601,567,535,505,477
  1522.         dc.w    450,425,401,379,357,337,318,300,284,268,253,238
  1523.         dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  1524. ; Tuning -6
  1525.         dc.w    894,844,796,752,709,670,632,597,563,532,502,474
  1526.         dc.w    447,422,398,376,355,335,316,298,282,266,251,237
  1527.         dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  1528. ; Tuning -5
  1529.         dc.w    887,838,791,746,704,665,628,592,559,528,498,470
  1530.         dc.w    444,419,395,373,352,332,314,296,280,264,249,235
  1531.         dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  1532. ; Tuning -4
  1533.         dc.w    881,832,785,741,699,660,623,588,555,524,494,467
  1534.         dc.w    441,416,392,370,350,330,312,294,278,262,247,233
  1535.         dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  1536. ; Tuning -3
  1537.         dc.w    875,826,779,736,694,655,619,584,551,520,491,463
  1538.         dc.w    437,413,390,368,347,328,309,292,276,260,245,232
  1539.         dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  1540. ; Tuning -2
  1541.         dc.w    868,820,774,730,689,651,614,580,547,516,487,460
  1542.         dc.w    434,410,387,365,345,325,307,290,274,258,244,230
  1543.         dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  1544. ; Tuning -1
  1545.         dc.w    862,814,768,725,684,646,610,575,543,513,484,457
  1546.         dc.w    431,407,384,363,342,323,305,288,272,256,242,228
  1547.         dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  1548.  
  1549. mt_chan1temp    dc.l    0,0,0,0,0,$00010000,0,0,0,0,0,0
  1550. mt_chan2temp    dc.l    0,0,0,0,0,$00020000,0,0,0,0,1,0
  1551. mt_chan3temp    dc.l    0,0,0,0,0,$00040000,0,0,0,0,2,0
  1552. mt_chan4temp    dc.l    0,0,0,0,0,$00080000,0,0,0,0,3,0
  1553.  
  1554. mt_SampleStarts dc.l    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  1555.                 dc.l    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  1556.  
  1557. mt_SongDataPtr  dc.l 0
  1558.  
  1559. scroll          dc.l    0
  1560.  
  1561. noteplayer      dc.l    0
  1562.  
  1563. mt_PatternPos   dc.w 0
  1564. mt_DMACONtemp   dc.w 0
  1565.  
  1566. seqadj          dc.w    0               ; < Fix - for old modules
  1567. blkadj          dc.w    0
  1568.  
  1569. mt_speed        dc.b 0
  1570. mt_counter      dc.b 0
  1571. mt_SongPos      dc.b 0
  1572. mt_PBreakPos    dc.b 0
  1573. mt_PosJumpFlag  dc.b 0
  1574. mt_PBreakFlag   dc.b 0
  1575. mt_LowMask      dc.b 0
  1576. mt_PattDelTime  dc.b 0
  1577. mt_PattDelTime2 dc.b 0,0
  1578.  
  1579. modfilter       dc.b    0
  1580.  
  1581. playing         dc.b    0
  1582.  
  1583. name            dc.b    "Sound/Noise/ProTracker",0
  1584.  
  1585.         end